/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package io;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import tal.drivechain.chain.AbortChainException;
import tal.drivechain.matchers.VarMatcher;
import tal.drivechain.plugin.Channel;
import tal.drivechain.plugin.Module;
import tal.drivechain.variable.types.DataType;
import tal.drivechain.variable.SetProperty.Flag;
import tal.drivechain.variable.Variable;

/**
 *
 * @author Main
 */
public class FileOut extends Module {
    File file = null;
    VarMatcher writeTrigger, addTrigger;
    List<Variable> variables = new ArrayList<Variable>();
    boolean textOutput;
    
    @Override
    public void setupProperties() throws IllegalArgumentException, AbortChainException {
        setFilename(props.getProperty("filename"), null);
        setAddTrigger(props.getProperty("addTrigger"), null);
        setWriteTrigger(props.getProperty("writeTrigger"), null);
        setTextOutput(props.getProperty("textOutput"), null);
    }

    public void setFilename(Object value, Flag flag) {
        if (value==null)
            file = null;
        else file = (File)value;
    } public Object getFilename() { return file; }

    public void setAddTrigger(Object value, Flag flag) {
        addTrigger = (VarMatcher)value;
    } public Object getAddTrigger() { return addTrigger; }

    public void setWriteTrigger(Object value, Flag flag) {
        writeTrigger = (VarMatcher)value;
    } public Object getWriteTrigger() { return writeTrigger; }

    public void setTextOutput(Object value, Flag flag) {
        textOutput = (Boolean)value;
    } public Object getTextOutput() { return textOutput; }

    @Override
    protected void msgReceived(Variable in, long timestamp, Channel channel) {
        if (file==null) return;
        if (addTrigger.matches(in, channel, this) && !in.getDataType().matches(DataType.EVENT)) {
            //add to buffer
            if (infoFlag)
                log("Adding variable to buffer: " + in.toString(this), MSG.INFO);
            variables.add(in);
        }
        if (writeTrigger.matches(in, channel, this)) {
            try {
                if (infoFlag)
                    log("Writing to '" + file + "'", MSG.INFO);
                writeFile(file);
            } catch (IOException ex) {
                log("While trying to write file '" + file + "': " + ex.getMessage(), MSG.WARNING);
            } 
        } 
    }


    private void writeFile(File file) throws IOException {
        if (textOutput) {
            Writer out = new BufferedWriter(new FileWriter(file));
            try {
                for (Variable var : variables)
                    out.write(var.getValue(this).toString());
            } finally { out.close(); }
        } else {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
            out.writeObject(variables);
        }

        if (infoFlag)
            log("Clearing buffer.", MSG.INFO);
        variables.clear();
    }
    
}
